#include "sal.h"
#include "ctc_cli.h"
#include "usw/include/drv_enum.h"
#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "usw/include/drv_chip_ctrl.h"
#include "ctc_dkit.h"
#include "ctc_dkit_common.h"
#include "ctc_usw_dkit.h"
#include "ctc_usw_dkit_interface.h"
#include "ctc_tmm_dkit_serdes.h"

#define CTC_DKITS_TMM_SENSOR_TIMEOUT 1000
#define CTC_DKITS_TMM_MAX_CHIP_SENSOR 7

extern ctc_dkit_chip_api_t* g_dkit_chip_api[CTC_DKITS_MAX_LOCAL_CHIP_NUM];

#define SYS_TMM_GROUP_ID(group_id, queue_id, group_mode) \
    { \
        if (DKITS_IS_BIT_SET(queue_id, 13)) \
        {\
            group_id = (((queue_id & 0x2000) >> 3) + ((queue_id & 0x1FFF) >> 4));\
        }\
        else \
        {\
            group_id = ((queue_id >> 4) << 1 |  ((queue_id >> 3) & group_mode));\
        }\
    } \

#define CTC_DKITS_TMM_MAX_MAC_NUM_PER_DP            160
#define CTC_DKITS_TMM_MAX_MAC_NUM                   CTC_DKITS_TMM_MAX_MAC_NUM_PER_DP*2
#define CTC_DKITS_TMM_MAX_SERDES_NUM                96
#define CTC_DKITS_TMM_MAX_MAC_NUM_PER_TXQM          40
#define CTC_DKITS_TMM_CPUMAC_START                  320
#define CTC_DKITS_TMM_CPUMAC_END                    323

struct ctc_dkits_tmm_logic_lane_to_pcs_mac_map_s
{
    uint8  pcs_idx;
    uint16 mac_id;
    uint8  is_x16;
    uint8 pcs_x8_x16_index;
    uint8 txqm_id;
};
typedef struct ctc_dkits_tmm_logic_lane_to_pcs_mac_map_s ctc_dkits_tmm_logic_lane_to_pcs_mac_map_t;

enum ctc_tmm_dkit_cpumac_interface_mode_s
{
    CTC_TMM_DKIT_CPUMAC_MODE_CG = 0,
    CTC_TMM_DKIT_CPUMAC_MODE_XLG,
    CTC_TMM_DKIT_CPUMAC_MODE_LG0,
    CTC_TMM_DKIT_CPUMAC_MODE_LG1,
    CTC_TMM_DKIT_CPUMAC_MODE_XXVG,
    CTC_TMM_DKIT_CPUMAC_MODE_SGMII,
    CTC_TMM_DKIT_CPUMAC_MODE_XFI,
    CTC_TMM_DKIT_CPUMAC_MODE_MAX
};
typedef enum ctc_tmm_dkit_cpumac_interface_mode_s ctc_tmm_dkit_cpumac_interface_mode_t;

int32
ctc_tmm_dkit_device_info(void* p_para)
{
    ctc_dkit_memory_para_t* p_memory_para = (ctc_dkit_memory_para_t*)p_para;
    uint8 lchip = 0;
    uint32 cmd = 0;
		
    GlobalChannelIdReg_m global_chan_id_cfg;

    DKITS_PTR_VALID_CHECK(p_para);
    CTC_DKIT_LCHIP_CHECK(p_memory_para->param[1]);

    CTC_DKIT_PRINT_DEBUG("%s()\n", __FUNCTION__);

    lchip = p_memory_para->param[1];
    DRV_INIT_CHECK(lchip);
    sal_memset(&global_chan_id_cfg, 0, sizeof(global_chan_id_cfg));
    cmd = DRV_IOR(GlobalChannelIdReg_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &global_chan_id_cfg);

    CTC_DKIT_PRINT("%-20s\n", "Internal Port Status");
    CTC_DKIT_PRINT("%-20s %-8s\n", "Type", "ChanId");

    CTC_DKIT_PRINT("-----------------------------\n");
    CTC_DKIT_PRINT("%-20s %-8d\n", "OAM",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, oamChannel0_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "ILOOP", CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, loopChannel1_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "ELOOP", CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, loopChannel1_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "DMA_0",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, dmaChannel0_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "DMA_1",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, dmaChannel1_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "DMA_2",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, dmaChannel2_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "DMA_3",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, dmaChannel3_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "CPU_0",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, cpuChannel0_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "CPU_1",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, cpuChannel1_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "CPU_2",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, cpuChannel2_f, &global_chan_id_cfg)));
    CTC_DKIT_PRINT("%-20s %-8d\n", "CPU_3",  CTC_DKITS_CHANNEL_DECODE(GetGlobalChannelIdReg(V, cpuChannel3_f, &global_chan_id_cfg)));
    return CLI_SUCCESS;
}

#define CTC_DKIT_MONITOR_QUEUE_BASE_CTL 11264
#define CTC_DKIT_MONITOR_QUEUE_BASE_CPU 2048
#define CTC_DKIT_MONITOR_QUEUE_MAX_CPU 2176
#define CTC_DKIT_MONITOR_CTL_QUEUE_NUM 4

int32
ctc_tmm_dkit_monitor_get_channel_by_queue_id(uint8 lchip, uint16 queue_id)
{
    uint32 cmd = 0;
    uint8  link_to_port = 0;
    uint32 parent_id_grp = 0;
    uint32 parent_id_L3 = 0;
    uint32 parent_id_L2 = 0;
    uint32 parent_id_L1 = 0;
    uint32 channel = 0;
    uint32 sub_grp_id = 0;
    DsQMgrL3ParentSelect_m parent_select_L3;
    DsQMgrL2ParentSelect_m parent_select_L2;
    DsQMgrL1ParentSelect_m parent_select_L1;
    DsQMgrL0ParentSelect_m parent_select_L0;
    DsQMgrGrpParentSelect_m  que_grp_parent;
 
    CTC_DKIT_PRINT_DEBUG("%s()\n", __FUNCTION__);
	
    sal_memset(&que_grp_parent, 0, sizeof(DsQMgrGrpParentSelect_m));
    sal_memset(&parent_select_L3, 0, sizeof(DsQMgrL3ParentSelect_m));
    sal_memset(&parent_select_L2, 0, sizeof(DsQMgrL3ParentSelect_m));
    sal_memset(&parent_select_L1, 0, sizeof(DsQMgrL1ParentSelect_m));
    sal_memset(&parent_select_L0, 0, sizeof(DsQMgrL0ParentSelect_m));

    if(queue_id >= CTC_DKIT_MONITOR_QUEUE_BASE_CTL)
    {
         channel = (queue_id - CTC_DKIT_MONITOR_QUEUE_BASE_CTL) /CTC_DKIT_MONITOR_CTL_QUEUE_NUM;
    }
    else if (queue_id >= CTC_DKIT_MONITOR_QUEUE_BASE_CPU && queue_id < CTC_DKIT_MONITOR_QUEUE_MAX_CPU)
    {
	   channel = 120;
    } 
    else 	
    {
        SYS_TMM_GROUP_ID(sub_grp_id, queue_id, 1)
        cmd = DRV_IOR(DsQMgrGrpParentSelect_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, sub_grp_id, cmd, &que_grp_parent);
        link_to_port = GetDsQMgrGrpParentSelect(V, linkToPortEn_f, &que_grp_parent);
        if (link_to_port)
        {
             channel = GetDsQMgrGrpParentSelect(V, parentId_f, &que_grp_parent);
        }
        else
        {
	      parent_id_grp = GetDsQMgrGrpParentSelect(V, parentId_f, &que_grp_parent);

	      cmd = DRV_IOR(DsQMgrL3ParentSelect_t, DRV_ENTRY_FLAG);
             DRV_IOCTL(lchip, parent_id_grp, cmd, &parent_select_L3);
             parent_id_L3 = GetDsQMgrL3ParentSelect(V, parentId_f, &parent_select_L3);

	      cmd = DRV_IOR(DsQMgrL2ParentSelect_t, DRV_ENTRY_FLAG);
             DRV_IOCTL(lchip, parent_id_L3, cmd, &parent_select_L2);
             parent_id_L2 = GetDsQMgrL2ParentSelect(V, parentId_f, &parent_select_L2);

             cmd = DRV_IOR(DsQMgrL1ParentSelect_t, DRV_ENTRY_FLAG);
             DRV_IOCTL(lchip, parent_id_L2, cmd, &parent_select_L1);
             parent_id_L1 = GetDsQMgrL1ParentSelect(V, parentId_f, &parent_select_L1);

             cmd = DRV_IOR(DsQMgrL0ParentSelect_t, DRV_ENTRY_FLAG);
             DRV_IOCTL(lchip, parent_id_L1, cmd, &parent_select_L0);
             channel = GetDsQMgrL0ParentSelect(V, parentId_f, &parent_select_L0);
         }
     }
    return channel;
}

uint32
ctc_tmm_dkit_monitor_get_channel_by_gport(uint8 lchip, uint16 gport)
{
    uint16 lport = 0;
    uint16 gchip = 0;
    uint32 channel = 0xFFFFFFFF;
    uint32 cmd = 0;
    DsQWriteDestPortChannelMap_m qwrite_dest_port_chan_map;
    
    CTC_DKIT_PRINT_DEBUG("%s()\n", __FUNCTION__);

    sal_memset(&qwrite_dest_port_chan_map, 0, sizeof(DsQWriteDestPortChannelMap_m));
    lport = CTC_DKIT_CTC_GPORT_TO_SYS_LPORT(gport);
    CTC_DKIT_GET_GCHIP(lchip, gchip);
    if (gchip != CTC_DKIT_CTC_GPORT_TO_GCHIP(gport))
    {
        return channel;
    }
    cmd = DRV_IOR(DsQWriteDestPortChannelMap_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, lport, cmd, &qwrite_dest_port_chan_map);
    channel = GetDsQWriteDestPortChannelMap(V, channelId_f, &qwrite_dest_port_chan_map);

    return CTC_DKITS_CHANNEL_DECODE(channel);
}

STATIC int32
_ctc_tmm_dkit_interface_cpumac_show_pcs_status(uint8 lchip, uint16 mac_id)
{
    char* pcs_mode_str[CTC_TMM_DKIT_CPUMAC_MODE_MAX] = { "CG", "XLG", "LG (LGMode0)", "LG (LGMode1)", "XXVG", "SGMII","XFI" };
    ctc_tmm_dkit_cpumac_interface_mode_t pcs_mode = CTC_TMM_DKIT_CPUMAC_MODE_XFI;
    uint8 mode_idx             = 0;
    uint8 inner_id             = mac_id - CTC_DKITS_TMM_CPUMAC_START;
    uint32 tbl_id              = 0;
    uint32 cmd                 = 0; 
    uint32 index               = 0;
    uint32 value               = 0;
    uint32 XFI_PLACE_HOLDER    = 0xffffffff;
    SharedPcsCfg_m             shared_pcs_cfg;
    
    uint32 tbl_info[CTC_TMM_DKIT_CPUMAC_MODE_MAX][3] = {
        /*SharedPcsCfg_t.filed   pcs_status tbl,  step*/
        {SharedPcsCfg_cgMode_f,                   SharedPcsCgStatus_t,      0}, /*CTC_TMM_DKIT_CPUMAC_MODE_CG*/                                                
        {SharedPcsCfg_xlgMode_f,                  SharedPcsXlgStatus_t,     0}, /*CTC_TMM_DKIT_CPUMAC_MODE_XLG*/                                                
        {SharedPcsCfg_lgMode0_f,                  SharedPcsXlgStatus_t,     0}, /*CTC_TMM_DKIT_CPUMAC_MODE_LG0*/                                            
        {SharedPcsCfg_lgMode1_f,                  SharedPcsLgStatus_t,      0}, /*CTC_TMM_DKIT_CPUMAC_MODE_LG1*/
        /*CTC_TMM_DKIT_CPUMAC_MODE_XXVG*/
        {SharedPcsCfg_xxvgMode0_f + inner_id,     SharedPcsXfi0Status_t,    SharedPcsXfi1Status_t - SharedPcsXfi0Status_t}, 
        /*CTC_TMM_DKIT_CPUMAC_MODE_SGMII*/
        {SharedPcsCfg_sgmiiModeRx0_f + inner_id,  SharedPcsSgmii0Status_t,  SharedPcsSgmii1Status_t - SharedPcsSgmii0Status_t}, 
        /*CTC_TMM_DKIT_CPUMAC_MODE_XFI*/
        {XFI_PLACE_HOLDER,                        SharedPcsXfi0Status_t,    SharedPcsXfi1Status_t - SharedPcsXfi0Status_t}      
    };

    /*1. get pcs mode*/
    tbl_id = SharedPcsCfg_t;    
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, index, cmd, &shared_pcs_cfg);

    for(mode_idx = 0; mode_idx < CTC_TMM_DKIT_CPUMAC_MODE_XFI; mode_idx ++)
    {
        DRV_IOR_FIELD(lchip, tbl_id, tbl_info[mode_idx][0], &value, &shared_pcs_cfg);
        if(value)
        {
            pcs_mode = mode_idx;
            break;
        }
    }

    /*2. check mac_id*/
    if((CTC_TMM_DKIT_CPUMAC_MODE_CG == pcs_mode) || 
            (CTC_TMM_DKIT_CPUMAC_MODE_XLG == pcs_mode)  || 
                    (CTC_TMM_DKIT_CPUMAC_MODE_LG0 == pcs_mode))
    {
        if(CTC_DKITS_TMM_CPUMAC_START != mac_id)
        {
            CTC_DKIT_PRINT("Mac id %d is invalid!\n", mac_id);
            return CLI_ERROR;
        }
    }
    else if(CTC_TMM_DKIT_CPUMAC_MODE_LG1 == pcs_mode)
    {
        if((CTC_DKITS_TMM_CPUMAC_START + 2) != mac_id)
        {
            CTC_DKIT_PRINT("Mac id %d is invalid!\n", mac_id);
            return CLI_ERROR;
        }
    }

    /*3. get pcs status tbl */
    if(CTC_TMM_DKIT_CPUMAC_MODE_XXVG <= pcs_mode)
    {
        tbl_id = tbl_info[pcs_mode][1] + (mac_id - CTC_DKITS_TMM_CPUMAC_START)*tbl_info[pcs_mode][2];
    }
    else
    {
        tbl_id = tbl_info[pcs_mode][1];
    }

    /*4. show pcs status tbl */
    if (tbl_id != MaxTblId_t)
    {
        CTC_DKIT_PRINT("%% CPUMAC , MII Inner Lane Id = %d, PCS Inner Lane Id  = %d, mode = %s\n", inner_id, inner_id, pcs_mode_str[pcs_mode]);
        CTC_DKIT_PRINT("%% read %s 0\n", TABLE_NAME(lchip, tbl_id));
        CTC_DKIT_PRINT("%% mac pcs status---->\n");
        ctc_usw_dkit_interface_print_pcs_table(lchip, tbl_id, index);
    }
    else
    {
        CTC_DKIT_PRINT("Cannot match mac mode!!!");
    }
    
    return CLI_SUCCESS;
}

STATIC int32
_ctc_tmm_dkit_interface_get_pcs_mac_map_by_mac(uint8 lchip, uint16 mac_id, ctc_dkits_tmm_logic_lane_to_pcs_mac_map_t* pcs_mac_map)
{
    uint8 index = 0;
    ctc_dkits_tmm_logic_lane_to_pcs_mac_map_t ctc_dkits_tmm_lane_2_pcs_mac_map[CTC_DKITS_TMM_MAX_SERDES_NUM] =
    {
        /************* DP0 start *************/
        /* TXQM0 HSS0, support QSGMII */
        /*pcs_idx mac_id  is_x16 pcs_x8_x16_index txqm_id*/
        {0,        0,       TRUE,        0,       0},
        {1,        4,       TRUE,        0,       0},
        {2,        8,       TRUE,        0,       0},
        {3,       12,       TRUE,        0,       0},
        {4,       16,       TRUE,        0,       0},
        {5,       20,       TRUE,        0,       0},
        {6,       24,       TRUE,        0,       0},
        {7,       28,       TRUE,        0,       0},
        /* TXQM0 HSS1, DO NOT support QSGMII */
        { 8,      32,       TRUE,        0,       0},
        { 9,      33,       TRUE,        0,       0},
        {10,      34,       TRUE,        0,       0},
        {11,      35,       TRUE,        0,       0},
        {12,      36,       TRUE,        0,       0},
        {13,      37,       TRUE,        0,       0},
        {14,      38,       TRUE,        0,       0},
        {15,      39,       TRUE,        0,       0},
        /* TXQM1 HSS2, support QSGMII */
        {0,       40,       TRUE,        1,       1},
        {1,       44,       TRUE,        1,       1},
        {2,       48,       TRUE,        1,       1},
        {3,       52,       TRUE,        1,       1},
        {4,       56,       TRUE,        1,       1},
        {5,       60,       TRUE,        1,       1},
        {6,       64,       TRUE,        1,       1},
        {7,       68,       TRUE,        1,       1},
        /* TXQM1 HSS3, DO NOT support QSGMII */
        { 8,      72,       TRUE,        1,       1},
        { 9,      73,       TRUE,        1,       1},
        {10,      74,       TRUE,        1,       1},
        {11,      75,       TRUE,        1,       1},
        {12,      76,       TRUE,        1,       1},
        {13,      77,       TRUE,        1,       1},
        {14,      78,       TRUE,        1,       1},
        {15,      79,       TRUE,        1,       1},
        /* TXQM2 HSS4, DO NOT support QSGMII */
        {0,       80,       FALSE,       0,       2},
        {1,       81,       FALSE,       0,       2},
        {2,       82,       FALSE,       0,       2},
        {3,       83,       FALSE,       0,       2},
        {4,       84,       FALSE,       0,       2},
        {5,       85,       FALSE,       0,       2},
        {6,       86,       FALSE,       0,       2},
        {7,       87,       FALSE,       0,       2},
        /* TXQM3 HSS5, DO NOT support QSGMII */
        {0,       120,      FALSE,       1,       3},
        {1,       121,      FALSE,       1,       3},
        {2,       122,      FALSE,       1,       3},
        {3,       123,      FALSE,       1,       3},
        {4,       124,      FALSE,       1,       3},
        {5,       125,      FALSE,       1,       3},
        {6,       126,      FALSE,       1,       3},
        {7,       127,      FALSE,       1,       3},
        /************* DP0 end *************/
        
        /************* DP1 start *************/
        /* TXQM0 HSS0, support QSGMII */
        {0,       160,      TRUE,        2,       4},
        {1,       164,      TRUE,        2,       4},
        {2,       168,      TRUE,        2,       4},
        {3,       172,      TRUE,        2,       4},
        {4,       176,      TRUE,        2,       4},
        {5,       180,      TRUE,        2,       4},
        {6,       184,      TRUE,        2,       4},
        {7,       188,      TRUE,        2,       4},
        /* TXQM0 HSS1, DO NOT support QSGMII */
        { 8,      192,      TRUE,        2,       4},
        { 9,      193,      TRUE,        2,       4},
        {10,      194,      TRUE,        2,       4},
        {11,      195,      TRUE,        2,       4},
        {12,      196,      TRUE,        2,       4},
        {13,      197,      TRUE,        2,       4},
        {14,      198,      TRUE,        2,       4},
        {15,      199,      TRUE,        2,       4},
        /* TXQM1 HSS2, support QSGMII */
        {0,       200,      TRUE,        3,       5},
        {1,       204,      TRUE,        3,       5},
        {2,       208,      TRUE,        3,       5},
        {3,       212,      TRUE,        3,       5},
        {4,       216,      TRUE,        3,       5},
        {5,       220,      TRUE,        3,       5},
        {6,       224,      TRUE,        3,       5},
        {7,       228,      TRUE,        3,       5},
        /* TXQM1 HSS3, DO NOT support QSGMII */
        { 8,      232,      TRUE,        3,       5},
        { 9,      233,      TRUE,        3,       5},
        {10,      234,      TRUE,        3,       5},
        {11,      235,      TRUE,        3,       5},
        {12,      236,      TRUE,        3,       5},
        {13,      237,      TRUE,        3,       5},
        {14,      238,      TRUE,        3,       5},
        {15,      239,      TRUE,        3,       5},
        /* TXQM2 HSS4, DO NOT support QSGMII */
        {0,       240,      FALSE,       2,       6},
        {1,       241,      FALSE,       2,       6},
        {2,       242,      FALSE,       2,       6},
        {3,       243,      FALSE,       2,       6},
        {4,       244,      FALSE,       2,       6},
        {5,       245,      FALSE,       2,       6},
        {6,       246,      FALSE,       2,       6},
        {7,       247,      FALSE,       2,       6},
        /* TXQM3 HSS5, DO NOT support QSGMII */
        {0,       280,      FALSE,       3,       7},
        {1,       281,      FALSE,       3,       7},
        {2,       282,      FALSE,       3,       7},
        {3,       283,      FALSE,       3,       7},
        {4,       284,      FALSE,       3,       7},
        {5,       285,      FALSE,       3,       7},
        {6,       286,      FALSE,       3,       7},
        {7,       287,      FALSE,       3,       7},
        /************* DP1 end *************/
    };

    for(index = 0; index < CTC_DKITS_TMM_MAX_SERDES_NUM; index ++)
    {
        if(mac_id == ctc_dkits_tmm_lane_2_pcs_mac_map[index].mac_id)
        {
            pcs_mac_map->pcs_idx = ctc_dkits_tmm_lane_2_pcs_mac_map[index].pcs_idx;
            pcs_mac_map->mac_id = ctc_dkits_tmm_lane_2_pcs_mac_map[index].mac_id;
            pcs_mac_map->is_x16 = ctc_dkits_tmm_lane_2_pcs_mac_map[index].is_x16;
            pcs_mac_map->pcs_x8_x16_index = ctc_dkits_tmm_lane_2_pcs_mac_map[index].pcs_x8_x16_index;
            pcs_mac_map->txqm_id = ctc_dkits_tmm_lane_2_pcs_mac_map[index].txqm_id;

            break;
        }
    }

    if(CTC_DKITS_TMM_MAX_SERDES_NUM == index)
    {
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

int32
ctc_tmm_dkit_interface_show_pcs_status(uint8 lchip, uint16 mac_id)
{
    ctc_dkits_tmm_logic_lane_to_pcs_mac_map_t pcs_mac_map;
    int32 ret            = 0;
    uint8 dp_id          = 0;
    uint8 txqm_mac_id    = 0;
    uint16 fixed_mac_id  = mac_id;
    uint32 index         = 0;
    uint32 step          = 0;
    uint32 tbl_id        = 0;
    uint32 fld_id        = 0;
    uint32 cmd           = 0;
    uint32 tx_speed      = 0;
    uint32 is_qsgmii     = 0;
    char   buf2[20]      = {0};
    uint16 buf2_len      = 0;

    if((CTC_DKITS_TMM_CPUMAC_START <= mac_id) && (mac_id <= CTC_DKITS_TMM_CPUMAC_END))
    {
        ret = _ctc_tmm_dkit_interface_cpumac_show_pcs_status(lchip, mac_id);
        return ret;
    }

    /*1. get pcs_mac_map info by mac*/
    if((mac_id <= 31) || ((40 <= mac_id) && (mac_id <= 71)) || ((160 <= mac_id) && (mac_id <= 191)) || ((200 <= mac_id) && (mac_id <= 231)))
    {
        /*support QSGMII*/
        fixed_mac_id = mac_id - (mac_id % 4);
    }
    ret = _ctc_tmm_dkit_interface_get_pcs_mac_map_by_mac(lchip,  fixed_mac_id, &pcs_mac_map);

    if(CLI_ERROR == ret)
    {
        CTC_DKIT_PRINT("Mac id %d is invalid!\n", mac_id);
        return CLI_ERROR;
    }

    txqm_mac_id = mac_id % CTC_DKITS_TMM_MAX_MAC_NUM_PER_TXQM;
    dp_id = pcs_mac_map.txqm_id < 4 ? 0 : 1;

    /*2. get s_qsgmii flag*/
    index = DRV_INS(pcs_mac_map.txqm_id, 0);
    step = McMacMiiRxCfg_cfgMcMacMiiRx_1_cfgMcMacMiiQsgmiiMod_f - McMacMiiRxCfg_cfgMcMacMiiRx_0_cfgMcMacMiiQsgmiiMod_f;
    fld_id = McMacMiiRxCfg_cfgMcMacMiiRx_0_cfgMcMacMiiQsgmiiMod_f + step * txqm_mac_id;
    cmd = DRV_IOR(McMacMiiRxCfg_t, fld_id);
    DRV_FIELD_IOCTL(lchip, index, cmd, &is_qsgmii);

    if((fixed_mac_id != mac_id) && (!is_qsgmii))
    {
        CTC_DKIT_PRINT("Mac id %d is unused!\n", mac_id);
        return CLI_ERROR;
    }

    /*3. check mac used status*/
    index = DRV_INS(pcs_mac_map.txqm_id, 0);
    step = McMacMiiTxCfg_cfgMcMacMiiTx_1_cfgMcMacTxSpeed_f - McMacMiiTxCfg_cfgMcMacMiiTx_0_cfgMcMacTxSpeed_f;
    fld_id = McMacMiiTxCfg_cfgMcMacMiiTx_0_cfgMcMacTxSpeed_f + step * txqm_mac_id;
    cmd = DRV_IOR(McMacMiiTxCfg_t, fld_id);
    DRV_FIELD_IOCTL(lchip, index, cmd, &tx_speed);

    if(0 == tx_speed)
    {
        CTC_DKIT_PRINT("Mac id %d is unused!\n", mac_id);
        return CLI_ERROR;
    }

    /*4. get pcs satus tbl*/
    if (pcs_mac_map.is_x16)
    {
        if (is_qsgmii)
        {
            tbl_id = McPcsX16LanesQsgmiiMon_t;
        }
        else
        {
            tbl_id = McPcsX16LanesRxChanMon_t;
        }
    }
    else
    {
        tbl_id = McPcsX8LanesRxChanMon_t;
    }
    index = DRV_INS(pcs_mac_map.pcs_x8_x16_index, 0);

    /*5. show pcs status tbl */
    if (tbl_id != MaxTblId_t)
    {
        CTC_DKIT_PRINT("%% Dp Id = %d, TXQM ID = %d, TXQM Inner Mac ID = %d, PCS_X8_X16_ID = %d, PCS Inner Lane Id = %d\n", dp_id, 
                                        pcs_mac_map.txqm_id, txqm_mac_id, pcs_mac_map.pcs_x8_x16_index, pcs_mac_map.pcs_idx);
        CTC_DKIT_PRINT("%% read %s 0 inst %d\n", TABLE_NAME(lchip, tbl_id), pcs_mac_map.pcs_x8_x16_index);
        CTC_DKIT_PRINT("%% mac pcs status---->\n");
        buf2_len = pcs_mac_map.pcs_idx > 9 ? 19 : 18;
        sal_snprintf(buf2, buf2_len, "monRxStatusChan_%u_", pcs_mac_map.pcs_idx);
        ctc_usw_dkit_interface_print_pcs_table_grep(lchip, tbl_id, index, buf2, buf2_len);
    }
    else
    {
        CTC_DKIT_PRINT("Cannot match mac mode!!!");
    }

    return CLI_SUCCESS;
}

int32
ctc_tmm_dkit_monitor_sensor(uint8 lchip, ctc_dkit_monitor_sensor_t type, uint32* p_value)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 timeout = CTC_DKITS_TMM_SENSOR_TIMEOUT;
    uint32 index = 0;
    uint8  loop = 0;
    uint8 base_vol = 0;  /*0:1024mv 1: 1232mv*/
    uint32 ref_vol = 1024;
    uint32 sensor[CTC_DKITS_TMM_MAX_CHIP_SENSOR] = {OmcMemTL_t, OmcMemTR_t, OmcMemBL_t, OmcMemBL_t, OmcMemBR_t, OmcMemBR_t, OmcMemTR_t};

    uint32 count = 0;
    ds_t ds;

    DKITS_PTR_VALID_CHECK(p_value);
    if (CTC_DKIT_MONITOR_SENSOR_VOL != type) /*only support get serdes voltage*/
    {
        return CLI_ERROR;
    }

    base_vol = p_value[0];
    ref_vol = base_vol?1232:1024;
    /* 
    tmm temperature max return 4 value,  voltage max return 6 value , senser vol max return 7 value
    other chip this capability maybe change need double check
    */
    count = 7;

    for (; loop < count; loop++)
    {
        index = 0xf;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = 0x313ff;
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 4);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        /*wait RTHMC_RST=1*/
        /*read tbl-reg OmcMem 0x10 offset 0x0*/
        timeout = CTC_DKITS_TMM_SENSOR_TIMEOUT;
        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        while(timeout)
        {
            timeout--;
            DRV_IOCTL(lchip,index, cmd, &ds);
            field_val = GetOmcMemTL(V, data_f, &ds);
            if (0 == DKITS_IS_BIT_SET(field_val, 4))
            {
                break;
            }
            sal_task_sleep(1);
        }
        if (0 == timeout)
        {
            return CLI_ERROR;
        }
        /*config ENBIAS=1ENVR=1ENAD=1*/
        /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x02000007 0x03000007*/
        index = 0x11;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 0);
        if (base_vol)
        {
            DKITS_BIT_UNSET(field_val, 1);
        }
        else
        {
            DKITS_BIT_SET(field_val, 1);
        }
        DKITS_BIT_SET(field_val, 2);
        DKITS_BIT_UNSET(field_val, 24);
        DKITS_BIT_SET(field_val, 25);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        sal_task_sleep(10);

        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 1);
        DKITS_BIT_UNSET(field_val, 8);
        DKITS_BIT_UNSET(field_val, 9);
        DKITS_BIT_UNSET(field_val, 10);
        DKITS_BIT_UNSET(field_val, 11);
        if (loop == 0)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003*/
            DKITS_BIT_SET(field_val, 8);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }
        if (loop == 1)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003*/
            DKITS_BIT_SET(field_val, 8);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }
        if (loop == 2)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            DKITS_BIT_SET(field_val, 8);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }

        if (loop == 3)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            DKITS_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }

        if (loop == 4)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            DKITS_BIT_SET(field_val, 8);

            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }

        if (loop == 5)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            DKITS_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }
        if (loop == 6)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000203*/
            DKITS_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, cmd, &ds);
        }
        /*mask_write tbl-reg OmcMem 0x8 offset 0x0 0x00000004 0x00000004*/
        index = 0x8;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 2);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);

        /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
        index = 0x12;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 0);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        
        /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000000 0x00000001*/
        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_UNSET(field_val, 0);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        sal_task_sleep(10);

        /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
        index = 0x12;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 0);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);

        /*Wait((mask_read tbl-reg OmcMem 0xa offset 0x0 0x00000004) =1)*/
        index = 0xa;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        timeout = CTC_DKITS_TMM_SENSOR_TIMEOUT;
        while(timeout)
        {
            timeout--;
            (DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            if (DKITS_IS_BIT_SET(field_val, 2))
            {
                break;
            }
            sal_task_sleep(1);
        }
        if (0 == timeout)
        {
            return CLI_ERROR;
        }

        /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x00000006 0x00000006*/
        index = 0x11;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        DKITS_BIT_SET(field_val, 1);
        DKITS_BIT_SET(field_val, 2);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &ds);
        sal_task_sleep(10);

        /*read-reg OmcMem 0xc offset 0x0*/
        index = 0xc;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip,index, cmd, &ds);
        field_val = GetOmcMemTL(V, data_f, &ds);
        p_value[loop] = (field_val*1000)/ref_vol;
    }
    return CLI_SUCCESS;
}

int32 ctc_tmm_dkit_init(uint8 lchip)
{
    g_dkit_chip_api[lchip]->dkits_get_device_info = ctc_tmm_dkit_device_info;
    g_dkit_chip_api[lchip]->dkits_monitor_sensor = ctc_tmm_dkit_monitor_sensor;
    g_dkit_chip_api[lchip]->dkits_get_channel_by_queue = ctc_tmm_dkit_monitor_get_channel_by_queue_id;
    g_dkit_chip_api[lchip]->dkits_get_channel_by_gport = ctc_tmm_dkit_monitor_get_channel_by_gport;
    g_dkit_chip_api[lchip]->dkits_dump_serdes_status = ctc_tmm_dkit_misc_serdes_status;
    g_dkit_chip_api[lchip]->dkits_read_serdes = ctc_tmm_dkit_misc_read_serdes;
    g_dkit_chip_api[lchip]->dkits_write_serdes = ctc_tmm_dkit_misc_write_serdes;
    g_dkit_chip_api[lchip]->dkits_serdes_ctl = ctc_tmm_dkit_misc_serdes_ctl;
    g_dkit_chip_api[lchip]->dkits_serdes_resert = ctc_tmm_dkit_misc_serdes_resert;
    g_dkit_chip_api[lchip]->dkits_serdes_fw_reg = ctc_tmm_dkit_misc_serdes_fw_reg;
    g_dkit_chip_api[lchip]->dkits_show_pcs_status = ctc_tmm_dkit_interface_show_pcs_status;
    g_dkit_chip_api[lchip]->dkits_serdes_diag  = ctc_tmm_dkit_misc_serdes_diag;
    return 0;
}


